package se.rende.myrss.data;


import static android.provider.BaseColumns._ID;
import static se.rende.myrss.data.Constants.AUTHORITY;
import static se.rende.myrss.data.Constants.CONTENT_URI_CHANNEL;
import static se.rende.myrss.data.Constants.CONTENT_URI_ITEM;
import se.rende.myrss.R;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.text.TextUtils;

public class MyRSSContentProvider extends ContentProvider {
	private static final int CHANNELS = 1;
	private static final int CHANNELS_ID = 2;
	private static final int ITEMS = 3;
	private static final int ITEMS_ID = 4;
	private static final String CHANNEL_CONTENT_TYPE = "vnd.android.cursor.dir/vnd.se.rende.myrss.channel";
	private static final String CHANNEL_CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.se.rende.myrss.channel";
	private static final String ITEM_CONTENT_TYPE = "vnd.android.cursor.dir/vnd.se.rende.myrss.item";
	private static final String ITEM_CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.se.rende.myrss.item";

	private MyRSSDataHelper myRssData;
	private UriMatcher uriMatcher;

	@Override
	public boolean onCreate() {
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		uriMatcher.addURI(AUTHORITY, "channel", CHANNELS);
		uriMatcher.addURI(AUTHORITY, "channel/#", CHANNELS_ID);
		uriMatcher.addURI(AUTHORITY, "item", ITEMS);
		uriMatcher.addURI(AUTHORITY, "item/#", ITEMS_ID);
		myRssData = new MyRSSDataHelper(getContext());
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String orderBy) {
		Cursor cursor = null;
		int match = uriMatcher.match(uri);
		if (match == CHANNELS_ID || match == CHANNELS) {
			if (match == CHANNELS_ID) {
				long id = Long.parseLong(uri.getPathSegments().get(1));
				selection = appendRowId(selection, id);
			}
			// Get the database and run the query
			SQLiteDatabase db = myRssData.getReadableDatabase();
			cursor = db.query("channel", projection, selection,
					selectionArgs, null, null, orderBy);
		} else if (match == ITEMS_ID || match == ITEMS) {
			if (match == ITEMS_ID) {
				long id = Long.parseLong(uri.getPathSegments().get(1));
				selection = appendRowId(selection, id);
			}
			// Get the database and run the query
			SQLiteDatabase db = myRssData.getReadableDatabase();
			cursor = db.query("item", projection, selection,
					selectionArgs, null, null, orderBy);
		} else {
			throw new IllegalArgumentException(getContext().getString(R.string.alert_message_unknown_uri) + " " + uri + " match=" + match);
		}

		// Tell the cursor what uri to watch, so it knows when its
		// source data changes
		cursor.setNotificationUri(getContext().getContentResolver(), uri);
		return cursor;
	}

	@Override
	public String getType(Uri uri) {
		switch (uriMatcher.match(uri)) {
		case CHANNELS:
			return CHANNEL_CONTENT_TYPE;
		case CHANNELS_ID:
			return CHANNEL_CONTENT_ITEM_TYPE;
		case ITEMS:
			return ITEM_CONTENT_TYPE;
		case ITEMS_ID:
			return ITEM_CONTENT_ITEM_TYPE;
		default:
			throw new IllegalArgumentException(getContext().getString(R.string.alert_message_unknown_uri) + " " + uri);
		}
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		Uri newUri = null;
		SQLiteDatabase db = myRssData.getWritableDatabase();

		// Validate the requested uri
		if (uriMatcher.match(uri) == CHANNELS) {
			// Insert into database
			long id = db.insertOrThrow("channel", null, values);
			
			// Notify any watchers of the change
			newUri = ContentUris.withAppendedId(CONTENT_URI_CHANNEL, id);
		} else if (uriMatcher.match(uri) == ITEMS) {	
			// Insert into database
			long id = db.insertOrThrow("item", null, values);
			
			// Notify any watchers of the change
			newUri = ContentUris.withAppendedId(CONTENT_URI_ITEM, id);
		} else {
			throw new IllegalArgumentException(getContext().getString(R.string.alert_message_unknown_uri) + " " + uri);
		}
		getContext().getContentResolver().notifyChange(newUri, null);
		return newUri;
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		SQLiteDatabase db = myRssData.getWritableDatabase();
		int count;
		long id;
		switch (uriMatcher.match(uri)) {
		case CHANNELS:
			count = db.delete("channel", selection, selectionArgs);
			break;
		case CHANNELS_ID:
			id = Long.parseLong(uri.getPathSegments().get(1));
			db.delete("item", "channel_id=" + id, null);
			String whereClause = appendRowId(selection, id);
			count = db.delete("project", whereClause, selectionArgs);
			break;
		case ITEMS:
			count = db.delete("item", selection, selectionArgs);
			break;
		case ITEMS_ID:
			id = Long.parseLong(uri.getPathSegments().get(1));
			count = db.delete("item", appendRowId(selection, id), selectionArgs);
			break;
		default:
			throw new IllegalArgumentException(getContext().getString(R.string.alert_message_unknown_uri) + " " + uri);
		}

		// Notify any watchers of the change
		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		SQLiteDatabase db = myRssData.getWritableDatabase();
		int count;
		long id;
		switch (uriMatcher.match(uri)) {
		case CHANNELS:
			count = db.update("channel", values, selection, selectionArgs);
			break;
		case CHANNELS_ID:
			id = Long.parseLong(uri.getPathSegments().get(1));
			count = db.update("channel", values, appendRowId(selection, id),
					selectionArgs);
			break;
		case ITEMS:
			count = db.update("item", values, selection, selectionArgs);
			break;
		case ITEMS_ID:
			id = Long.parseLong(uri.getPathSegments().get(1));
			count = db.update("item", values, appendRowId(selection, id),
					selectionArgs);
			break;
		default:
			throw new IllegalArgumentException(getContext().getString(R.string.alert_message_unknown_uri) + " " + uri);
		}

		// Notify any watchers of the change
		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	/** Append an id test to a SQL selection expression */
	private String appendRowId(String selection, long id) {
		return _ID
				+ "="
				+ id
				+ (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')'
						: "");
	}

}